home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / dpmigcc5.zip / RSX / SOURCE / FPU-EMU / REG_NORM.S < prev    next >
Text File  |  1994-05-27  |  3KB  |  151 lines

  1. /*---------------------------------------------------------------------------+
  2.  |  reg_norm.S                                                               |
  3.  |                                                                           |
  4.  | Copyright (C) 1992,1993,1994                                              |
  5.  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  6.  |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
  7.  |                                                                           |
  8.  | Normalize the value in a FPU_REG.                                         |
  9.  |                                                                           |
  10.  | Call from C as:                                                           |
  11.  |   void normalize(FPU_REG *n)                                              |
  12.  |                                                                           |
  13.  |   void normalize_nuo(FPU_REG *n)                                          |
  14.  |                                                                           |
  15.  +---------------------------------------------------------------------------*/
  16.  
  17. #include "fpu_asm.h"
  18.  
  19.  
  20. .text
  21.  
  22.     .align 2,144
  23. .globl _normalize
  24.  
  25. _normalize:
  26.     pushl    %ebp
  27.     movl    %esp,%ebp
  28.     pushl    %ebx
  29.  
  30.     movl    PARAM1,%ebx
  31.  
  32. #ifdef PARANOID
  33.     cmpb    TW_Valid,TAG(%ebx)
  34.     je    L_ok
  35.  
  36.     pushl    $0x220
  37.     call    _exception
  38.     addl    $4,%esp
  39.  
  40. L_ok:
  41. #endif PARANOID
  42.  
  43.     movl    SIGH(%ebx),%edx
  44.     movl    SIGL(%ebx),%eax
  45.  
  46.     orl    %edx,%edx    /* ms bits */
  47.     js    L_done        /* Already normalized */
  48.     jnz    L_shift_1    /* Shift left 1 - 31 bits */
  49.  
  50.     orl    %eax,%eax
  51.     jz    L_zero        /* The contents are zero */
  52.  
  53.     movl    %eax,%edx
  54.     xorl    %eax,%eax
  55.     subl    $32,EXP(%ebx)    /* This can cause an underflow */
  56.  
  57. /* We need to shift left by 1 - 31 bits */
  58. L_shift_1:
  59.     bsrl    %edx,%ecx    /* get the required shift in %ecx */
  60.     subl    $31,%ecx
  61.     negl    %ecx
  62.     shld    %cl,%eax,%edx
  63.     shl    %cl,%eax
  64.     subl    %ecx,EXP(%ebx)    /* This can cause an underflow */
  65.  
  66.     movl    %edx,SIGH(%ebx)
  67.     movl    %eax,SIGL(%ebx)
  68.  
  69. L_done:
  70.     cmpl    EXP_OVER,EXP(%ebx)
  71.     jge    L_overflow
  72.  
  73.     cmpl    EXP_UNDER,EXP(%ebx)
  74.     jle    L_underflow
  75.  
  76. L_exit:
  77.     popl    %ebx
  78.     leave
  79.     ret
  80.  
  81.  
  82. L_zero:
  83.     movl    EXP_UNDER,EXP(%ebx)
  84.     movb    TW_Zero,TAG(%ebx)
  85.     jmp    L_exit
  86.  
  87. L_underflow:
  88.     push    %ebx
  89.     call    _arith_underflow
  90.     pop    %ebx
  91.     jmp    L_exit
  92.  
  93. L_overflow:
  94.     push    %ebx
  95.     call    _arith_overflow
  96.     pop    %ebx
  97.     jmp    L_exit
  98.  
  99.  
  100.  
  101. /* Normalise without reporting underflow or overflow */
  102.     .align 2,144
  103. .globl _normalize_nuo
  104.  
  105. _normalize_nuo:
  106.     pushl    %ebp
  107.     movl    %esp,%ebp
  108.     pushl    %ebx
  109.  
  110.     movl    PARAM1,%ebx
  111.  
  112. #ifdef PARANOID
  113.     cmpb    TW_Valid,TAG(%ebx)
  114.     je    L_ok_nuo
  115.  
  116.     pushl    $0x221
  117.     call    _exception
  118.     addl    $4,%esp
  119.  
  120. L_ok_nuo:
  121. #endif PARANOID
  122.  
  123.     movl    SIGH(%ebx),%edx
  124.     movl    SIGL(%ebx),%eax
  125.  
  126.     orl    %edx,%edx    /* ms bits */
  127.     js    L_exit        /* Already normalized */
  128.     jnz    L_nuo_shift_1    /* Shift left 1 - 31 bits */
  129.  
  130.     orl    %eax,%eax
  131.     jz    L_zero        /* The contents are zero */
  132.  
  133.     movl    %eax,%edx
  134.     xorl    %eax,%eax
  135.     subl    $32,EXP(%ebx)    /* This can cause an underflow */
  136.  
  137. /* We need to shift left by 1 - 31 bits */
  138. L_nuo_shift_1:
  139.     bsrl    %edx,%ecx    /* get the required shift in %ecx */
  140.     subl    $31,%ecx
  141.     negl    %ecx
  142.     shld    %cl,%eax,%edx
  143.     shl    %cl,%eax
  144.     subl    %ecx,EXP(%ebx)    /* This can cause an underflow */
  145.  
  146.     movl    %edx,SIGH(%ebx)
  147.     movl    %eax,SIGL(%ebx)
  148.     jmp    L_exit
  149.  
  150.  
  151.